/*
抽象操作的运行流程，一般是下面这样。
*/
1. Let result be AbstractOp().
2. If result is an abrupt completion,
3.
return result.
4. Set result to result. [
	[Value]
].
5.
return result.

/*
上面的第一步调用了抽象操作AbstractOp()，得到result，这是一个 Completion Record。
第二步，如果result属于 abrupt completion，就直接返回
。如果此处没有返回，表示result属于 normal completion。
第三步，将result的值设置为resultCompletionRecord.[[Value]]。
第四步，返回result。
*/

/*
ES6 规格将这个标准流程，使用简写的方式表达。
*/
Let result be AbstractOp().
ReturnIfAbrupt(result).
return result.
/*
这个简写方式里面的ReturnIfAbrupt(result)，就代表了上面的第二步和第三步，即如果有报错，就返回错误，否则取出值。
*/

/*
甚至还有进一步的简写格式。
*/
Let result be ? AbstractOp().
return result.
/*
上面流程的?，就代表AbstractOp()可能会报错。一旦报错，就返回错误，否则取出值。
*/


/*
除了?，ES 6 规格还使用另一个简写符号!。
*/

Let result be!AbstractOp().
return result.

/*
上面流程的!，代表AbstractOp() 不会报错， 返回的一定是 normal completion， 总是可以取出值。
*/
